package com.example.clone;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.example.utils.Zmlib;

public final class Client implements android.os.Handler.Callback {
	public static interface Callback {
		void callback(boolean result);
	}

	public static final int PORT = 8889;
	private String serverip;
	private Context context;
	private Handler handler;
	private ProgressDialog pd;
	private int count;
	
	public Client(Context context) {
		this.context = context;
		handler = new Handler(this);
	}

	@Override
	public boolean handleMessage(Message msg) {
		switch (msg.what) {
		case 1:{
			if(pd == null) {
				pd = new ProgressDialog(context);
				pd.setMessage("正在查找服务器...");
				pd.setMax(255);
				pd.setCancelable(false);
				pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
				pd.show();
			}
			break;
		}
		case 2:
			if(pd != null)
				pd.setProgress(msg.arg1);
			break;
		case 3: {
			if(pd != null) {
				pd.dismiss();
				pd = null;
				String serverip = msg.getData().getString("serverip");
				Callback callback = (Callback) msg.obj;
				if (serverip != null) {
					Zmlib.toast(context, "服务器IP：" + serverip);
					this.serverip = serverip;
				}
				if(callback != null) {
					callback.callback(serverip == null ? false : true);
				}
			}
			break;
		}
		case 4:{
			count++;
			if(pd == null) {
				pd = new ProgressDialog(context);
				pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
//				pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
				pd.setTitle(this.serverip);
				pd.setMessage("正在下载...");
				pd.setCancelable(false);
				pd.show();
				break;
			}
		}
		case 5:
/*			switch (msg.arg1) {
			case 1:
				pd.setMax(msg.arg2);
				break;
			case 2:
				pd.setProgress(msg.arg2);
				break;
			default:
				break;
			}
*/			break;
		case 6:
			count--;
			if(pd != null && count < 1) {
				pd.dismiss();
				pd = null;
			}
			Callback callback = (Callback) msg.obj;
			if (callback != null) {
				if(msg.arg1 == 1234) {// 下载成功
					callback.callback(true);
				} else {
					callback.callback(false);
				}
			}
			break;
		default:
			return false;
		}
		return true;
	}

	public String getServerip() {
		return serverip;
	}

	/**
	 * 查找服务器
	 */
	public void searchServer(final Callback callback) {
		final String ipv4 = Zmlib.getLocalIpAddress();
		if (ipv4 == null) {
			Zmlib.msgBoxOk(context, "未连接网络", null);
			return;
		}
		new Thread() {
			public void run() {
				handler.sendEmptyMessage(1);
				String ipPrefix = ipv4.substring(0, ipv4.lastIndexOf('.') + 1);
				DatagramSocket ds = null;
				String serverip = null;
				try {
					ds = new DatagramSocket();
					ds.setSoTimeout(10);
					String helloworld = "helloworld";
					byte[] buf = helloworld.getBytes();
					DatagramPacket dp = new DatagramPacket(buf, buf.length);
					dp.setPort(PORT);
					for (int i = 1; i < 255; i++) {// 查找服务器
						handler.obtainMessage(2, i, 0).sendToTarget();
						try {
							String str = ipPrefix + i;
							dp.setAddress(InetAddress.getByName(str));
							ds.send(dp);
							ds.send(dp);
							ds.send(dp);
							ds.send(dp); //多发几次
							
							if(i==254) {
								ds.setSoTimeout(2000);
							}
							
							ds.receive(dp);
							str = new String(dp.getData(), 0, dp.getLength());
							if (str.equals(helloworld)) {
								serverip = dp.getAddress().getHostAddress();
								break;
							}
						} catch (SocketTimeoutException e) {
							// 故意超时
						}
					}
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					try {
						ds.close();
					} catch (Exception e) {

					}
				}
				Message msg = new Message();
				msg.what = 3;
				msg.obj = callback;
				Bundle data = new Bundle();
				data.putString("serverip", serverip);
				msg.setData(data);
				handler.sendMessage(msg);
			}
		}.start();

	}

	/**
	 * 自动搜索服务器，并下载服务器文件（请先调用{@link #searchServer(Context)}）
	 * 
	 * @param context
	 * @param serverFile
	 *            服务器指定路径上的文件，如果为""返回服务器apk
	 * @param localStoreFile
	 *            本地存储文件
	 * @param callback
	 */
	public void download(final String serverFile, final String localStoreFile,
			final Callback callback) {
		new Thread() {
			@Override
			public void run() {
				handler.sendEmptyMessage(4);
				if (serverip != null) {
					OutputStream fileOut = null;
					Socket socket = null;
					try {
						socket = new Socket(serverip, PORT);
						socket.setSoTimeout(10000);
						DataOutputStream netOut = new DataOutputStream(
								socket.getOutputStream());
						netOut.writeUTF(serverFile);// 请求

						DataInputStream netInput = new DataInputStream(
								socket.getInputStream());
						int total = (int) netInput.readLong();
						handler.obtainMessage(5, 1, total).sendToTarget();
						int count = 0;
						byte[] buf = new byte[Server.BUFFER_SIZE];
						int len;
						File f = new File(localStoreFile);
						Zmlib.ensureFileExists(f);
						fileOut = new FileOutputStream(f);// 本地存储
						while ((len = netInput.read(buf)) != -1) {
							count += len;
							handler.obtainMessage(5, 2, count).sendToTarget();
							fileOut.write(buf, 0, len);
						}
						Log.e("haha",count+"/"+total
								);
						handler.obtainMessage(6, 1234, 0, callback).sendToTarget();
						return;
					} catch(SocketTimeoutException e) {
						
					} catch (IOException e) {
						e.printStackTrace();
					} finally {
						try {
							fileOut.close();
						} catch (Exception e) {

						}
						try {
							socket.close();
						} catch (Exception e) {

						}
					}
				}
				handler.obtainMessage(6, callback).sendToTarget();
				return;
			}
		}.start();
	}
}